home *** CD-ROM | disk | FTP | other *** search
/ Alles Voor Internet / Tout Pour Internet / alles voor internet.iso / MacInternet™ / Telnet / Terminal 2.2 / Project / Sources / Text.c < prev    next >
Text File  |  1992-01-17  |  4KB  |  171 lines

  1. /*
  2.     Terminal 2.2
  3.     "Text.c"
  4. */
  5.  
  6. #ifdef THINK_C
  7. #include "MacHeaders"
  8. #endif
  9. #ifdef applec
  10. #pragma load ":(Objects):MacHeadersMPW"
  11. #pragma segment Main2
  12. #endif
  13.  
  14. #include "Text.h"
  15.  
  16. /* ----- Remove last character from text buffer ------------------------ */
  17.  
  18. Byte RemoveCharacter(register TextRecord *p)
  19. {
  20.     register Byte *buffer;
  21.     register long new;
  22.     register Byte c;
  23.  
  24.     buffer = p->text;
  25.     new = p->newChar;
  26.  
  27.     if (p->length) {
  28.         new = new ? new - 1 : p->size - 1;
  29.         if (buffer[new] == '\015')
  30.             return 0;                /* Cannot delete previous line */
  31.         c = buffer[new];
  32.         buffer[new] = '\015';
  33.         p->newChar = new;
  34.         --(p->length);
  35.         return c;                    /* OK, character deleted */
  36.     }
  37.     return 0;                        /* Nothing to delete */
  38. }
  39.  
  40. /* ----- Add new character to text buffer ------------------------------ */
  41.  
  42. void AddNewCharacter(
  43.     register TextRecord *p,
  44.     register Byte c)
  45. {
  46.     register Byte *buffer;
  47.     register long first, new, max;
  48.  
  49.     buffer = p->text;
  50.     first = p->firstChar;
  51.     new = p->newChar;
  52.     max = p->size;
  53.  
  54.     buffer[new++] = c;        /* Save character in buffer */
  55.     if (new >= max)            /* Wrap around */
  56.         new = 0;
  57.     p->newChar = new;        /* Update new pointer for next character */
  58.     if (c == '\015')            /* Cariage return */
  59.         ++(p->lines);        /* One more line */
  60.  
  61.     if (new == first) {        /* Biting in our tail */
  62.         if (buffer[first] == '\015')
  63.             --(p->lines);    /* One line less */
  64.         ++first;            /* We lost the oldest character */
  65.         if (first >= max)    /* Wrap around */
  66.             first = 0;
  67.         p->firstChar = first;
  68.     } else
  69.         ++(p->length);
  70.  
  71.     buffer[new++] = '\015';    /* Always keep CR here */
  72.     if (new >= max)            /* Wrap around */
  73.         new = 0;
  74.     p->viewChar = new;        /* Offset to 1st character of new line */
  75.     p->viewLine = p->lines;
  76. }
  77.  
  78. /* ----- Find a line --------------------------------------------------- */
  79.  
  80. Boolean FindLine(
  81.     register TextRecord *p,
  82.     register long line,            /* Line number to look for */
  83.     Byte *str)                    /* String for result */
  84. {
  85.     register long offset;        /* Character offset of a character... */
  86.     register long number;        /* ...in this line */
  87.     register Byte *buffer;
  88.     register Byte *s;
  89.     register long max;
  90.     register Byte c;
  91.     Boolean lastLine;
  92.  
  93.     if (p->length == 0) {
  94.         *str = 0;
  95.         return TRUE;
  96.     }
  97.     buffer = p->text;
  98.     max = p->size;
  99.     lastLine = (line >= (p->lines - 1));
  100.  
  101.     /*
  102.         Three line numbers with character offsets are known:
  103.         (A)    line    0            at offset    p->firstChar
  104.         (B)    line    p->viewLine    at offset    p->viewChar
  105.         (C)    line    p->lines    at offset    (p->newChar + 1) % p->size
  106.  
  107.         So, first find out the one of those three line numbers
  108.         that is the nearest to the line we are looking for.
  109.     */
  110.  
  111.     if (line > p->viewLine) {
  112.         if (line > (p->viewLine + (p->lines - p->viewLine)/2)) {
  113.             offset = p->newChar + 1;    /* (C) */
  114.             if (offset >= max)
  115.                 offset = 0;
  116.             number = p->lines;
  117.         } else {
  118.             offset = p->viewChar;        /* (B) */
  119.             number = p->viewLine;
  120.         }
  121.     } else {
  122.         if (line > p->viewLine/2) {
  123.             offset = p->viewChar;        /* (B) */
  124.             number = p->viewLine;
  125.         } else {
  126.             offset = p->firstChar;        /* (A) */
  127.             number = 0;
  128.         }
  129.     }
  130.     p->viewLine = line + 1;        /* Remember this for later */
  131.  
  132.     /* Find line */
  133.  
  134.     if (line >= number) {        /* Look forward to find line */
  135.         line -= number;            /* Number of lines (CRs) to skip */
  136.         while (line) {
  137.             if (buffer[offset++] == '\015')
  138.                 line--;
  139.             if (offset >= max)    /* Wrap around */
  140.                 offset = 0;
  141.         }
  142.     } else {                    /* Look backwards to find line */
  143.         line = number-line+1;    /* Number of lines (CRs) to skip */
  144.         while (line) {
  145.             if (offset == 0)    /* Wrap around */
  146.                 offset = max;
  147.             if (buffer[--offset] == '\015')
  148.                 line--;
  149.         }
  150.         offset++;                /* We are at CR of previous line */
  151.         if (offset >= max)        /* Wrap around */
  152.             offset = 0;
  153.     }
  154.  
  155.     /* Now copy line */
  156.  
  157.     s = str;
  158.     number = 0;
  159.     while ((c = buffer[offset++]) != '\015') {
  160.         if (offset >= max)        /* Wrap around */
  161.             offset = 0;
  162.         *(++s) = c;
  163.         ++number;
  164.     }
  165.     if (offset >= max)            /* Wrap around */
  166.         offset = 0;
  167.     p->viewChar = offset;        /* Remember offset of next line */
  168.     str[0] = number;
  169.     return lastLine;
  170. }
  171.